﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using PI_CS_Tools;

namespace  PI_CS_Library.Virtual_Network_Information_Model
{
    public class VirtualNetwork
    {
        Identification _id;
        Identification _vnoId;
        Dictionary<int, Matrix> _matrixList;
        Dictionary<int, Link> _linkList;
        Dictionary<int, NetworkConnection> _networkConnectionList;
        Dictionary<int, NwTTP> _nwTtpList;

        public VirtualNetwork(Identification _vnoId)
        {
            _matrixList = new Dictionary<int, Matrix>();
            _linkList = new Dictionary<int, Link>();

            _id = new Identification("Virtual Network of: " + _vnoId);

            this._vnoId = _vnoId;

            _networkConnectionList = new Dictionary<int, NetworkConnection>();
            _nwTtpList = new Dictionary<int, NwTTP>();
        }


        public Dictionary<int, Link> GetLinkList(string _request)
        {
            string[] _linkId = _request.Split(':');

            Dictionary<int, Link> _resultList = new Dictionary<int, Link>();
            
            foreach (string _id in _linkId)
            {
                _resultList.Add(Int32.Parse(_id), _linkList[Int32.Parse(_id)]);
            }

            return _resultList;
        }


        public Dictionary<int, Link> GetLinkListFromMatrixList(List<Matrix> _request, int _reqCapacity)
        {

            Dictionary<int, Link> _resultList = new Dictionary<int, Link>();
            Matrix src;
            Matrix trg;
            for (int i = 0; i < _request.Count - 1; i++)
            {
                src = _request[i];
                trg = _request[i + 1];

                foreach (Link l in _linkList.Values)
                {
                    if (l.SrcMatrix == src && l.SinkMatrix == trg && l.Parameters.AvailableCapacity >= _reqCapacity)
                    {
                        l.Parameters.AvailableCapacity -= _reqCapacity;
                        _resultList.Add(l.Id.Number, l);
                        break;
                    }
                }
                   
            }
            return _resultList;
        }

        public Identification Id
        {
            get { return _id; }
            set { _id = value; }
        }

        public Identification VnoId
        {
            get { return _vnoId; }
            set { _vnoId = value; }
        }

        public Dictionary<int, Matrix> MatrixList
        {
            get { return _matrixList; }
            set { _matrixList = value; }
        }

        public Dictionary<int, Link> LinkList
        {
            get { return _linkList; }
            set { _linkList = value; }
        }

        public Dictionary<int, NwTTP> NwTtpList
        {
            get { return _nwTtpList; }
            set { _nwTtpList = value; }
        }

        public int ConnectSink(int _sinkId, int _userLinkId, int _port, int _nodeId)
        {
            NwTTP _sink = _matrixList[_nodeId].AddNwTTP(_sinkId, _port, Direction.Sink);
            _sink.UserLinkId = _userLinkId;
            _nwTtpList.Add(_sink.Id.Number, _sink);

            return _sink.Id.Number;
        }

        public int ConnectSource(int _sourceId, int _userLinkId, int _port, int _nodeId)
        {
            NwTTP _source = _matrixList[_nodeId].AddNwTTP(_sourceId, _port, Direction.Source);
            _source.UserLinkId = _userLinkId;
            _nwTtpList.Add(_source.Id.Number, _source);

            return _source.Id.Number;
        }

        public Matrix GetMatrix(int _matrixId)
        {
            return _matrixList[_matrixId];
        }

        public NwTTP GetNwTTP(int _id)
        {
            return _nwTtpList[_id];
        }

        public void AddMatrix(Matrix _newMatrix)
        {
            _matrixList.Add(_newMatrix.Id.Number, _newMatrix);
        }

        public Link GetLink(int _linkId)
        {
            return _linkList[_linkId];
        }

        public void AddLink(Link _newLink)
        {
            _linkList.Add(_newLink.Id.Number, _newLink);
        }

        public void AddNetworkConnection(NetworkConnection item)
        {
            _networkConnectionList.Add(item.Id.Number, item);
        }

        public NetworkConnection GetNetworkConnection(int _id)
        {
            return _networkConnectionList[_id];
        }

        public void DeleteNetworkConnection(int _id)
        {
            _networkConnectionList.Remove(_id);
        }

        public override string ToString()
        {
            return Convert.ToString(_id.Number);
        }

    }
}
